package yi.master.coretest.message.process;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
import com.cryptography.neu.sm.SM2Result;
import com.cryptography.neu.sm.SM2Util;
import com.cryptography.neu.sm.SM4Util;
import com.cryptography.neu.sm.Util;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import yi.master.coretest.message.process.config.HeNanYsbGjjMsgProcessParameter;
import yi.master.coretest.message.process.util.ysb.MDFive;
import yi.master.coretest.message.process.util.ysb.YsbSM4Util;

import java.util.Date;
import java.util.Map;

/**
 *
 * 河南豫事办公积金加解密
 * @author xuwangcheng
 * @version 1.0.0
 * @description
 * @date 2020/6/5 9:44
 */
public class HeNanYsbGjjMessageProcess extends MessageProcess {
    public static final Logger LOGGER = Logger.getLogger(HeNanYsbGjjMessageProcess.class);
    private static HeNanYsbGjjMessageProcess heNanYsbGjjMessageProcess;

    private HeNanYsbGjjMessageProcess() {}

    public static HeNanYsbGjjMessageProcess getInstance() {
        if (heNanYsbGjjMessageProcess == null) {
            heNanYsbGjjMessageProcess = new HeNanYsbGjjMessageProcess();
        }

        return heNanYsbGjjMessageProcess;
    }

    @Override
    public String processRequestMessage(String requestMessage, Map<String, String> headers, String processParameter) {
        JSONObject obj = JSONObject.parseObject(processParameter);
        HeNanYsbGjjMsgProcessParameter parameter = JSONObject.toJavaObject(obj, HeNanYsbGjjMsgProcessParameter.class);

        //单独地市的请求头处理
        if (StringUtils.isNotBlank(parameter.getClientId()) && StringUtils.isNotBlank(parameter.getSecretKey())
                && MapUtil.isNotEmpty(headers)) {
            headers.put("partner", MDFive.getMD5(parameter.getClientId() + parameter.getSecretKey() + DateUtil.format(new Date(), "yyyyMMdd")));
        }

        return encrypt(parameter, requestMessage);
    }

    @Override
    public String processResponseMessage(String responseMessage, String processParameter) {
        JSONObject obj = JSONObject.parseObject(processParameter);
        HeNanYsbGjjMsgProcessParameter parameter = JSONObject.toJavaObject(obj, HeNanYsbGjjMsgProcessParameter.class);

        return decode(parameter, responseMessage);
    }


    private String encrypt(HeNanYsbGjjMsgProcessParameter parameter, String requestMessage) {
        if (StringUtils.isBlank(parameter.getPriKey()) || StringUtils.isBlank(parameter.getPubKey())) {
            LOGGER.error("河南豫事办公积金接口加密失败：私钥和公钥均不能为空！");
            return requestMessage;
        }
        JSONObject jsonObject = new JSONObject();
        try {
            byte[] secretKey = SM4Util.generateKey();
            String ciphertext = YsbSM4Util.encryptData_ECB(requestMessage, secretKey);
            SM2Result sm2Result = SM2Util.Sm2Sign(parameter.getPriKey(), ciphertext);
            String strKey = Util.byteToHex(secretKey);
            String skey = SM2Util.encrypt(parameter.getPubKey(), strKey);
            jsonObject.put("ciphertext", ciphertext);
            jsonObject.put("skey", skey);
            jsonObject.put("sign_r", sm2Result.str_r);
            jsonObject.put("sign_s", sm2Result.str_s);
        } catch (Exception e) {
            LOGGER.error("河南豫事办公积金接口加密失败", e);
            return requestMessage;
        }

        return jsonObject.toJSONString();
    }

    private String decode(HeNanYsbGjjMsgProcessParameter parameter, String responseMessage) {
        if (StringUtils.isBlank(parameter.getPriKey()) || StringUtils.isBlank(parameter.getPubKey())) {
            LOGGER.error("河南豫事办公积金接口解密失败：私钥和公钥均不能为空！");
            return responseMessage;
        }

        try {
            JSONObject jsonObject = JSONObject.parseObject(responseMessage);
            boolean verifySignResult = SM2Util.Sm2Verify(parameter.getPubKey(), jsonObject.getString("ciphertext")
                    , jsonObject.getString("sign_r"), jsonObject.getString("sign_s"));
            jsonObject.put("verifySignResult", verifySignResult);
            //验签不正确
            if (!verifySignResult) {
                return jsonObject.toJSONString();
            }
            byte[] secretKey = SM4Util.generateKey();
            String strKey = Util.byteToHex(secretKey);
            String skey = SM2Util.encrypt(parameter.getPubKey(), strKey);
            String decrypt = SM2Util.decrypt(parameter.getPriKey(), skey);
            byte[] secretKeyB = Util.hexStringToBytes_sy(decrypt);
            String strResult = YsbSM4Util.decryptData_ECB(jsonObject.getString("ciphertext"), secretKeyB);
            jsonObject.put("decodeResult", JSONObject.parse(strResult));

            return jsonObject.toJSONString();
        } catch (Exception e) {
            LOGGER.error("河南豫事办公积金接口解密失败", e);
            return responseMessage;
        }

    }
}
